import 'package:flutter/material.dart';

const String _name = "矿泉水"; //聊天帐号昵称

///
/// 聊天页面嵌入交互动画和IOS风格适配
/// 来源 https://segmentfault.com/a/1190000013712300
///
class FriendlychatApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      //创建一个MaterialApp控件对象，其下可塞入支持Material设计语言特性的控件
      title: "智能客服",
      home: new ChatScreen(), //主页面为用户自定义ChatScreen控件
    );
  }
}

//聊天主页面ChatScreen控件定义为一个有状态控件
class ChatScreen extends StatefulWidget {
  @override
  State createState() => new ChatScreenState();
}

//ChatScreenState状态中实现聊天内容的动态更新
class ChatScreenState extends State<ChatScreen> with TickerProviderStateMixin {
  // 存放聊天记录的数组，数组类型为无状态控件ChatMessage
  final List<ChatMessage> _messages = <ChatMessage>[];
  // 聊天窗口的文本输入控件
  final TextEditingController _textController = new TextEditingController();
  // 到ChatScreenState对象中定义一个标志位
  bool _isComposing = false;

  void _handleSubmitted(String text) {
    _textController.clear();
    setState(() {
      // 重置_isComposing 值
      _isComposing = false;
    });
    ChatMessage message = new ChatMessage(
      text: text,
      animationController: new AnimationController(
        duration: new Duration(milliseconds: 700), // 动画持续时间
        vsync: this, // 默认属性和参数
      ),
    );
    setState(() {
      _messages.insert(0, message);
    });
    message.animationController.forward(); // 启动动画
  }

  //定义文本输入框控件
  Widget _buildTextComposer() {
    return new IconTheme(
      data: new IconThemeData(color: Theme.of(context).accentColor),
      child: new Container(
        margin: const EdgeInsets.symmetric(horizontal: 8.0),
        child: new Row(
          children: <Widget>[
            new Flexible(
              child: new TextField(
                controller: _textController,
                // 通过onChanged事件更新_isComposing 标志位的值
                onChanged: (String text) {
                  // 调用setState函数重新渲染受到_isComposing变量影响的IconButton控件
                  setState(() {
                    // 如果文本输入框中的字符串长度大于0则允许发送消息
                    _isComposing = text.length > 0;
                  });
                },
                onSubmitted: _handleSubmitted,
                decoration: InputDecoration.collapsed(hintText: "发送消息"),
              ),
            ),
            new Container(
              margin: new EdgeInsets.symmetric(horizontal: 4.0),
              child: new IconButton(
                icon: new Icon(Icons.send),
                onPressed: _isComposing
                    ? () => _handleSubmitted(_textController.text)
                    : null, // 当没有为onPressed绑定处理函数时，IconButton默认为禁用状态
              ),
            ),
          ],
        ),
      ),
    );
  }

  //定义整个聊天窗口的页面元素布局
  Widget build(BuildContext context) {
    return new Scaffold(
      //页面脚手架
      appBar: new AppBar(title: new Text("客服中心")), //页面标题
      body: new Column(
        //Column使消息记录和消息输入框垂直排列
        children: <Widget>[
          new Flexible(
            //子控件可柔性填充，如果下方弹出输入框，使消息记录列表可适当缩小高度
            child: new ListView.builder(
              //可滚动显示的消息列表
              padding: new EdgeInsets.all(8.0),
              reverse: true, //反转排序，列表信息从下至上排列
              itemBuilder: (_, int index) => _messages[index], //插入聊天信息控件
              itemCount: _messages.length,
            ),
          ),
          new Divider(height: 1.0), //聊天记录和输入框之间的分隔
          new Container(
            decoration: new BoxDecoration(color: Theme.of(context).cardColor),
            child: _buildTextComposer(), //页面下方的文本输入控件
          ),
        ],
      ),
    );
  }

  @override
  void dispose() {
    // 遍历_messages数组，释放动效
    for (ChatMessage message in _messages) {
      message.animationController.dispose();
    }
    super.dispose();
  }
}

//单条聊天信息控件
class ChatMessage extends StatelessWidget {
  final String text;
  final AnimationController animationController;
  ChatMessage({this.text, this.animationController});

  @override
  Widget build(BuildContext context) {
    return new SizeTransition(
      //  用SizeTransition动效控件包裹整个控件，定义从小变大的动画效果
      sizeFactor: new CurvedAnimation(
        // CurvedAnimation定义动画播放的时间曲线
        parent: animationController,
        curve: Curves.easeOut,
      ), // 指定曲线类型
      axisAlignment: 0.0, // 对齐
      child: new Container(
        //modified  Container控件被包裹到SizeTransition中
        margin: const EdgeInsets.symmetric(vertical: 10.0),
        child: new Row(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            new Container(
              margin: const EdgeInsets.only(right: 16.0),
              child: new CircleAvatar(child: new Text(_name[0])),
            ),
            new Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: <Widget>[
                new Text(_name, style: Theme.of(context).textTheme.subhead),
                new Container(
                  margin: const EdgeInsets.only(top: 5.0),
                  child: new Text(text),
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }
}